home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 June / PCWorld_2007-06_cd.bin / v cisle / tclock / tclocklight-040702-3.exe / source / dll / bmp.c < prev    next >
C/C++ Source or Header  |  2003-12-29  |  3KB  |  138 lines

  1. /*-------------------------------------------------------------
  2.   bmp.c : read BMP file
  3.   (C) 1997-2003 Kazuto Sato
  4.   Please read readme.txt about the license.
  5.   
  6.   Written by Kazubon, Nanashi-san
  7. ---------------------------------------------------------------*/
  8.  
  9. #include "tcdll.h"
  10.  
  11. /* Globals */
  12.  
  13. HBITMAP ReadBitmap(HWND hwnd, const char* fname, BOOL b);
  14.  
  15. /* Static */
  16.  
  17. static int GetDibNumColors(const LPBITMAPINFOHEADER pbmih);
  18. static BYTE* GetDibBitsAddr(const BYTE* pDib);
  19.  
  20. /*--------------------------------------------------
  21.   read BMP file and return bitmap handle
  22. ----------------------------------------------------*/
  23. HBITMAP ReadBitmap(HWND hwnd, const char* fname, BOOL bTrans)
  24. {
  25.     BITMAPFILEHEADER bmfh;
  26.     BYTE* pDib;
  27.     DWORD size;
  28.     HFILE hf;
  29.     BITMAPINFOHEADER* pbmih;
  30.     BYTE* pDIBits;
  31.     HDC hdc;
  32.     int index;
  33.     HBITMAP hBmp;
  34.     
  35.     hf = _lopen(fname, OF_READ);
  36.     if(hf == HFILE_ERROR) return NULL;
  37.     
  38.     size = _llseek(hf, 0, 2) - sizeof(BITMAPFILEHEADER);
  39.     _llseek(hf, 0, 0);
  40.     
  41.     if(_lread(hf, (LPSTR)&bmfh, sizeof(BITMAPFILEHEADER)) !=
  42.         sizeof(BITMAPFILEHEADER))
  43.     {
  44.         _lclose(hf); return NULL;
  45.     }
  46.     
  47.     if(bmfh.bfType != *(WORD *)"BM")
  48.     {
  49.         _lclose(hf); return NULL;
  50.     }
  51.     
  52.     pDib = malloc(size);
  53.     if(pDib == NULL)
  54.     {
  55.         _lclose (hf); return NULL;
  56.     }
  57.     
  58.     if(_lread(hf, pDib, size) != size)
  59.     {
  60.         _lclose(hf); free(pDib);
  61.         return NULL;
  62.     }
  63.     _lclose(hf);
  64.     
  65.     pbmih = (BITMAPINFOHEADER*)pDib;
  66.     // don't support OS/2 format
  67.     if(pbmih->biSize != sizeof(BITMAPINFOHEADER))
  68.     {
  69.         free(pDib); return NULL;
  70.     }
  71.     // don't support RLE compression
  72.     if(pbmih->biCompression != BI_RGB &&
  73.         pbmih->biCompression != BI_BITFIELDS)
  74.     {
  75.         free(pDib); return NULL;
  76.     }
  77.     
  78.     if(pbmih->biCompression == BI_RGB)
  79.         pDIBits = GetDibBitsAddr(pDib);
  80.     else
  81.         pDIBits = pDib + sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
  82.     
  83.     if(bTrans) // pseudo transparency
  84.     {
  85.         if(pbmih->biBitCount == 1)
  86.             index = (*pDIBits & 0x80) >> 7;
  87.         else if(pbmih->biBitCount == 4)
  88.             index = (*pDIBits & 0xF0) >> 4;
  89.         else if(pbmih->biBitCount == 8)
  90.             index = *pDIBits;
  91.         if(pbmih->biBitCount <= 8)
  92.         {
  93.             COLORREF col = GetSysColor(COLOR_3DFACE);
  94.             ((BITMAPINFO*)pDib)->bmiColors[index].rgbBlue = GetBValue(col);
  95.             ((BITMAPINFO*)pDib)->bmiColors[index].rgbGreen = GetGValue(col);
  96.             ((BITMAPINFO*)pDib)->bmiColors[index].rgbRed = GetRValue(col);
  97.         }
  98.     }
  99.     
  100.     hdc = GetDC(hwnd);
  101.     hBmp = CreateDIBitmap(hdc,
  102.         (LPBITMAPINFOHEADER)pDib, CBM_INIT,
  103.         (LPSTR)pDIBits, (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
  104.     ReleaseDC(hwnd, hdc);
  105.     free(pDib);
  106.     return hBmp;
  107. }
  108.  
  109. /*--------------------------------------------------
  110.   return palette color numbers
  111. ----------------------------------------------------*/
  112. static int GetDibNumColors(const LPBITMAPINFOHEADER pbmih)
  113. {
  114.     int numColors;
  115.     int BitCount;
  116.     
  117.     BitCount = (int)pbmih->biBitCount;
  118.     numColors = (int)pbmih->biClrUsed;
  119.     if(numColors == 0)
  120.     {
  121.         if(BitCount <= 8) numColors = 1 << BitCount;
  122.         else numColors = 0;
  123.     }
  124.     return numColors;
  125. }
  126.  
  127. /*--------------------------------------------------
  128.   return DIB bits address
  129. ----------------------------------------------------*/
  130. static BYTE* GetDibBitsAddr(const BYTE* pDib)
  131. {
  132.     int numColors;
  133.     
  134.     numColors = GetDibNumColors((LPBITMAPINFOHEADER)pDib);
  135.     return (BYTE*)(pDib + sizeof(BITMAPINFOHEADER)
  136.         + sizeof(RGBQUAD) * numColors);
  137. }
  138.